#ifndef C_COMPILER_PREDICTTABLE_H
#define C_COMPILER_PREDICTTABLE_H

#include <Global.h>
#include <vector>

unordered_set<string> computeFirstToRightsSymbols(const vector<string>& symbols);

// 生成预测表的键
string getMapKey(const string& terminal, const string& nonTerminal) {
    return "{横坐标: " + terminal + "  纵坐标: " + nonTerminal + "}";
}

void setPrediction() {
    for (int i = 0; i < GRAMMARSIZE; ++i) {
        const Production& production = *productionsArray[i];
        if (production.right_string[0] == "$") {
            continue;   // 跳过类似于 value' -> $ 的文法
        }
        try {
            unordered_set<string>firstSet = computeFirstToRightsSymbols(production.right_string);
            for (const auto& terminal : firstSet) {
                if (terminal == "$") {
                    const auto& followSet = FollowSet.at(production.left_symbol);
                    for (const auto& followTerminal : followSet) {
                        predictionTable[getMapKey(followTerminal, production.left_symbol)] = i;
                    }
                } else {
                    predictionTable[getMapKey(terminal, production.left_symbol)] = i;
                }
            }
        } catch (const out_of_range& e) {
            cout << "First set does not contain key: " << production.right_string[0] << endl;
        }
    }
    for (int i = 0; i < GRAMMARSIZE; ++i) {
        const Production& production = *productionsArray[i];
        if(production.left_symbol=="tempA"){
            int stop;
        }
        if (production.right_string[0] == "$") {
            const auto& followSet = FollowSet.at(production.left_symbol);
            for (const auto& followTerminal : followSet) {
                predictionTable[getMapKey(followTerminal, production.left_symbol)] = i;
            }
        }
    }
}

//调用这个函数的时候需要先构建预测分析表
int getProductionIndex( int readerTop,int stackTop) {
    if (readerTop < 0 || readerTop >= readerVector.size() || stackTop < 0 || stackTop >= stackVector.size()) {
        cerr << "Error: Index out of bounds." << endl;
        return -1;
    }
    string terminal = map_i2s.at(readerVector[readerTop].first);
    string nonTerminal = stackVector[stackTop].first;
    string key = getMapKey(terminal, nonTerminal);
    auto it = predictionTable.find(key);
    if (it != predictionTable.end()) {
        if(nonTerminal=="elsePart" && terminal=="else"){
            return 43;
        }
        return it->second;
    } else {
        cerr << "Error: No production_map found for the given terminal and non-terminal." << endl;
        cerr << "Key : " << key << endl;
        return -1;
    }
}

// 新加函数！！！
// 计算右边符号串的整体FIRST集
unordered_set<string> computeFirstToRightsSymbols(const vector<string>& symbols) {
    unordered_set<string> result;
    for (const auto& symbol : symbols) {//分析所有符号
        if (VtSet.count(symbol)) {//如果是终结符，插入到结果中，直接返回
            result.insert(symbol);
            return result;
        }
        if (FirstSet.find(symbol) != FirstSet.end()) {//如果不是从头开始数的最后一个非终结符且first集含$，继续，否则断开
            const auto& firstSet = FirstSet[symbol];//找到当前非终结符的first集插入至result
            result.insert(firstSet.begin(), firstSet.end());
            if (firstSet.count("$") == 0) {//如果first集不含$，断开
                return result;
            }
        } else {
            cout << "Non-terminal " << symbol << " not found in FirstSet" << endl;
            break;
        }
    }
    result.erase("$");
    return result;
}

#endif //C_COMPILER_PREDICTTABLE_H
